var path = require('path');
var express = require('express');
var uuid = require('node-uuid');
var bodyParser = require('body-parser');
var url = require('url');
var fs    = require('fs');
var https = require('https');
var http = require('http');
var format = require('string-format');
format.extend(String.prototype);
var request = require('request');
var urlencode = require('urlencode');
const { callbackify } = require('util');

var svrTime = require("./plugin/svrTm");
var mysqlDB = require("./plugin/mysql");

console.log('start web server')

class TWeb{
    constructor(){
        this.config = {
            port: 20039 ,
            https:{
                enable:true ,
                keyFn:"D:/gitee/hhudev/svr/keys/4195813_wss.hhdata.cn.key",
                certFn:"D:/gitee/hhudev/svr/keys/4195813_wss.hhdata.cn.pem"
            }
        }

        this.statics = {
            "/":"D:/project/c6241016/c6241016_93251021/webs"
        }

        this.actionHandler = {
            
        }
        this.defaultAction= function( result , req , resp){
            result.error = "parameters is error." ;
            resp.send(JSON.stringify(result));
        }

        this.objs = {};
    }
    start( callback ){
        var me = this;
        try{
            var app = express();
            /*
            * 静态虚拟目录
            * */
            for (var sp in me.statics) {
                var webPath = me.statics[sp];
                app.use(sp, express.static(webPath));
            }
            /*
            * 动态路由
            * */
            var urlencodedParser = bodyParser.urlencoded({extended: false});
            app.use(urlencodedParser);
            app.use(bodyParser.json());
            var jsonParser = bodyParser.json();
            var apiPath ="/:appId/:module/:action";
            app.all(apiPath, jsonParser, function (req, res) {
                try{
                    var appId = req.params.appId;
                    var module = req.params.module;
                    var action = req.params.action;
                    
                    
                    res.header("Access-Control-Allow-Origin", "*");
                    res.header("Access-Control-Allow-Headers", "*");
                    res.header("Access-Control-Allow-Methods", "DELETE,PUT,POST,GET,OPTIONS");
                    var ps =req.query;
                    var result = {
                        appId: appId ,
                        module: module ,
                        action:action ,
                        ps: ps,
                        error: null,
                        result: null
                    };

                    var extend = function( a,b){
                        var res = {};
                        if( a && a!=null){
                            Object.keys(a).forEach( k=>{
                                res[k] = a[k];
                            })
                        }
                        if( b && a!=null){
                            Object.keys(b).forEach( k=>{
                                res[k] = b[k];
                            })
                        }
                        return  res;
                    }

                    var handler = function(result , req , resp){
                        var acKey = [appId , module , action].join("/");
                        if( me.actionHandler[acKey] ){
                            me.actionHandler[acKey]( result , req , resp );
                        }
                        else{
                            me.defaultAction(result , req , resp);
                        }
                    };
                    
                    if (req.method == "POST" ) {
                        if( req.headers && req.headers["content-type"] && req.headers["content-type"].indexOf('application/json')>=0 ){
                            ps = extend(ps, req.body);
                            handler( result , req , res);
                        }
                        else {
                            req.setEncoding('utf8');
                            req.on('data', function (data) {
                                try {
                                    var obj = JSON.parse(data);
                                    ps = extend(ps, obj);
                                } catch (ee) {
                                    console.log(ee)
                                }
                            });
                            req.on('end', function () {
                                handler( result , req , res);
                            });
                        }
                    } else if (req.method == "GET") {
                        handler( result , req , res);
                    }else if (req.method == "OPTIONS") {
                        res.setHeader('Access-Control-Allow-Headers','Content-Type,Access-Control-Allow-Headers,Authorization,X-Requested-With');
                        res.send(200);
                    }
                }
                catch(erHandler){
                    console.log(erHandler);
                    res.send(400);
                }
            });
            
            var options = {};
            try{
                if( me.config.https.enable){
                    options = {
                        key: fs.readFileSync(me.config.https.keyFn),
                        cert: fs.readFileSync(me.config.https.certFn)
                    };
                }
            }
            catch(eer){
                console.log(eer);
            }
            
            var webServer = me.config.https.enable? https.createServer(options, app):  http.createServer(options, app);

            webServer.listen(me.config.port, function (err) {
                me.objs.app  = app;
                me.objs.server = webServer;
                var msg = "start web server on :{protocol}://ip or domain:{port}/<appId>/<module>/<action>";
                msg = msg.format({
                    protocol: me.config.https.enable?"https":"http" ,
                    port: me.config.port 
                })
                console.log( msg);
                try{
                    if( callback && callback!=null){
                        callback();
                    }
                }
                catch(Ert){
                    console.log(Ert);
                }
            }); 
        }
        catch(ex){
            console.log(ex);
        }
    }
}

var appServer = new TWeb();
appServer.statics['/'] = "D:/project/c6241016/root";
appServer.statics['/data'] = "D:/project/c6241016/root/text";

var svrTm = new svrTime.TSvrTm();
svrTm.regist2Svr(appServer)

var db = new mysqlDB.TMySql();
db.regist2Svr(appServer);

appServer.start(  function(){
    console.log("app server is started.")
} )


